package v1

import (
	"fmt"
	"net/http"

	"server/global/e"
	"server/global/form"
	"server/global/response"
	"server/model"
	"server/service"
	"server/utils"

	"github.com/gin-gonic/gin"
)

type UserLoginForm struct {
	Username string `form:"username" valid:"Required;MaxSize(100)"`
	Password string `form:"password" valid:"Required;MaxSize(100)"`
}

// @Summary User Login
// @Produce  json
// @Param username query string true "userName"
// @Param password query string true "password"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/login [post]
func UserLogin(c *gin.Context) {
	var (
		r = response.Gin{C: c}
		f UserLoginForm
	)
	httpCode, errCode := form.BindAndValid(c, &f)
	if errCode != e.SUCCESS {
		r.Response(httpCode, errCode, nil)
		return
	}
	user := &model.User{Username: f.Username, Password: f.Password}
	// 检测用户是否存在
	userInfo, err := service.UserGet(*user)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_USER_NOT_EXIST, nil)
		return
	}
	if userInfo.ID <= 0 {
		r.Response(http.StatusOK, e.ERROR_USER_NOT_EXIST, nil)
		return
	}
	// 检测密码是否正确
	pwd := utils.GeneratePwd(f.Password, userInfo.Salt)
	if pwd != userInfo.Password {
		r.Response(http.StatusOK, e.ERROR_USER_PASSWORD, nil)
		return
	}
	// 生成token
	token, err := utils.GenerateToken(userInfo.Username, userInfo.Password)

	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_TOKEN_GENERATE, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, map[string]string{
		"token": token,
	})
}

// @Summary User Info
// @Produce  json
// @Param token query string true "token"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/info [get]
func UserInfo(c *gin.Context) {
	r := response.Gin{C: c}
	token := c.Query("token")
	// token解析
	info, err := utils.ParseToken(token)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_TOKEN, nil)
		return
	}
	user := &model.User{Username: info.Username}
	// 检测用户是否存在
	userInfo, err := service.UserGet(*user)
	if err != nil {
		r.Response(http.StatusUnauthorized, e.ERROR_USER_NOT_EXIST, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, userInfo)
}

type UserRegisterForm struct {
	Username string `form:"username" valid:"Required;MaxSize(100)"`
	Password string `form:"password" valid:"Required;MaxSize(32)"`
	Roles    string `form:"roles" valid:"Required;MaxSize(32)"`
}

// @Summary  User Register
// @Produce  json
// @Param username query string true "Username"
// @Param password query string true "Password"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/register [post]
func UserRegister(c *gin.Context) {
	var (
		r = response.Gin{C: c}
		f UserRegisterForm
	)

	httpCode, errCode := form.BindAndValid(c, &f)
	if errCode != e.SUCCESS {
		r.Response(httpCode, errCode, nil)
		return
	}

	// 生成登录秘钥和加密密码
	salt := utils.GenerateSalt()
	password := utils.GeneratePwd(f.Password, salt)

	user := &model.User{
		Username: f.Username,
		Password: password,
		Roles:    f.Roles,
		Salt:     salt,
		Avatar:   "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
	}
	// 检测用户是否存在
	isExist, err := service.UserIsExist(*user)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR, err)
		return
	}
	if isExist {
		r.Response(http.StatusOK, e.ERROR_USER_EXIST, nil)
		return
	}
	// 添加用户
	if err := service.UserAdd(*user); err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR, nil)
		return
	}
	r.Response(http.StatusOK, e.SUCCESS, nil)
}

// @Summary  User Logout
// @Produce  json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/logout [post]
func UserLogout(c *gin.Context) {
	r := response.Gin{C: c}
	r.Response(http.StatusOK, e.SUCCESS, nil)
}

// @Summary  Get Users
// @Produce  json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/users [get]
func GetUsers(c *gin.Context) {
	r := response.Gin{C: c}
	users, err := service.UserGets()
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_USER_GET, nil)
		return
	}
	r.Response(http.StatusOK, e.SUCCESS, users)
}

// @Summary  Get User
// @Produce  json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/{username} [get]
func GetUser(c *gin.Context) {
	r := response.Gin{C: c}
	user := &model.User{Username: c.Param("username")}
	userInfo, err := service.UserGet(*user)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_USER_GET, nil)
		return
	}
	r.Response(http.StatusOK, e.SUCCESS, userInfo)
}

type EditUserForm struct {
	ID int `form:"id" valid:"Min(1)"`
	// Uuid     string `form:"uuid" valid:"MaxSize(100)"`
	Username string `form:"username" valid:"MaxSize(100)"`
	NickName string `form:"nickname" valid:"MaxSize(100)" `
	Password string `form:"password" valid:"MaxSize(100)"`
	Roles    string `form:"roles" valid:"MaxSize(100)"`
	Salt     string `form:"salt" valid:"MaxSize(500)"`
	Avatar   string `form:"avatar" valid:"MaxSize(500)"`
}

// @Summary  Get User
// @Produce  json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user [put]
func EditUser(c *gin.Context) {
	var (
		r = response.Gin{C: c}
		f EditUserForm
	)

	httpCode, errCode := form.BindAndValid(c, &f)
	if errCode != e.SUCCESS {
		r.Response(httpCode, errCode, nil)
		return
	}

	// 生成登录秘钥和加密密码
	salt := utils.GenerateSalt()
	password := utils.GeneratePwd(f.Password, salt)

	user := model.User{
		ID:       f.ID,
		Username: f.Username,
		Password: password,
		Roles:    f.Roles,
		Salt:     salt,
		Avatar:   "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
	}
	fmt.Println(user)
	// 检测用户是否存在
	isExist, err := service.UserIsExistById(user)
	fmt.Println(user)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR, err)
		return
	}
	if !isExist {
		r.Response(http.StatusOK, e.ERROR_USER_NOT_EXIST, nil)
		return
	}
	// 修改用户
	err = service.UserEdit(user)
	fmt.Println(err)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR, nil)
		return
	}
	// fmt.Println(*user)
	r.Response(http.StatusOK, e.SUCCESS, nil)
}

// @Summary  Get User
// @Produce  json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/user/{username} [delete]
func DeleteUser(c *gin.Context) {
	r := response.Gin{C: c}
	user := &model.User{Username: c.Param("username")}
	fmt.Println(user)
	err := service.UserDelete(*user)
	fmt.Println(err)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR, nil)
		return
	}
	r.Response(http.StatusOK, e.SUCCESS, nil)
}
